package com.googlecode.jstructs.test.unwoven;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import org.junit.Test;

import com.googlecode.jstructs.runtime.ValueTypeStack;

/**
 * Shows how the transformed classes should look
 * 
 * @author Daniel Sperry 2010
 */
public class SimpleTest_UW {

	@Test
	public void constructorTest() {
		// Vector3 r = new Vector3(1, 2, 3);
		ValueTypeStack stack = ValueTypeStack.current();
		Vector3_UW._constructor(stack, 1, 2, 3);
		float r_x = stack.popFloat();
		float r_y = stack.popFloat();
		float r_z = stack.popFloat();
		assertEquals(1, r_x, 0);
		assertEquals(2, r_y, 0);
		assertEquals(3, r_z, 0);
	}

	@Test
	public void assignmentTest() {
		// Vector3 r = new Vector3(1, 2, 3);
		ValueTypeStack stack = ValueTypeStack.current();
		Vector3_UW._constructor(stack, 1, 2, 3);
		float r_x = stack.popFloat();
		float r_y = stack.popFloat();
		float r_z = stack.popFloat();

		// Vector3 s = new Vector3(4, 5, 6);
		Vector3_UW._constructor(stack, 4, 5, 6);
		float s_x = stack.popFloat();
		float s_y = stack.popFloat();
		float s_z = stack.popFloat();
		assertEquals(1, r_x, 0);
		assertEquals(2, r_y, 0);
		assertEquals(3, r_z, 0);
		assertEquals(4, s_x, 0);
		assertEquals(5, s_y, 0);
		assertEquals(6, s_z, 0);
		// r = s;
		r_x = s_x;
		r_y = s_y;
		r_z = s_z;
		//
		s_x = 40;
		s_y = 50;
		s_z = 60;
		assertEquals(40, s_x, 0);
		assertEquals(50, s_y, 0);
		assertEquals(60, s_z, 0);
		assertEquals(
				"r.x should be 4 because 'r = s' is a value copy not an instance copy",
				4, r_x, 0);
		assertEquals(5, r_y, 0);
		assertEquals(6, r_z, 0);
	}

	public void passingByValue_changeValue(Vector3_UW v) {
		v.x = 1000;
	}

	public void passingByValue_changeValue(ValueTypeStack stack, float v_x,
			float v_y, float v_z) {
		v_x = 1000;
	}

	@Test
	public void passingByValue() {
		// Vector3 r = new Vector3(1, 2, 3);
		ValueTypeStack stack = ValueTypeStack.current();
		Vector3_UW._constructor(stack, 1, 2, 3);
		float r_x = stack.popFloat();
		float r_y = stack.popFloat();
		float r_z = stack.popFloat();
		passingByValue_changeValue(stack, r_x, r_y, r_z);
		assertEquals(1, r_x, 0);
	}

	public Vector3_UW passingByValue2_changeValueAndReturn(Vector3_UW v) {
		v.x = 1000;
		return v;
	}

	public void passingByValue2_changeValueAndReturn(ValueTypeStack stack,
			float v_x, float v_y, float v_z) {
		v_x = 1000;
		stack.pushFloat(v_z);
		stack.pushFloat(v_y);
		stack.pushFloat(v_x);
	}

	@Test
	public void passingByValue2() {
		ValueTypeStack stack = ValueTypeStack.current();
		// Vector3_UW r = new Vector3_UW(1, 2, 3);
		Vector3_UW._constructor(stack, 1, 2, 3);
		float r_x = stack.popFloat();
		float r_y = stack.popFloat();
		float r_z = stack.popFloat();
		passingByValue2_changeValueAndReturn(stack, r_x, r_y, r_z);
		float s_x = stack.popFloat();
		@SuppressWarnings("unused")
		float s_y = stack.popFloat();
		@SuppressWarnings("unused")
		float s_z = stack.popFloat();

		assertEquals(1000, s_x, 0);
		assertEquals(1, r_x, 0);
	}

	@Test
	public void equalsOperatorTest() {
		ValueTypeStack stack = ValueTypeStack.current();
		// Vector3 s = new Vector3(1, 2, 3);
		Vector3_UW._constructor(stack, 1, 2, 3);
		float r_x = stack.popFloat();
		float r_y = stack.popFloat();
		float r_z = stack.popFloat();

		// Vector3 s = new Vector3(1, 2, 3);
		Vector3_UW._constructor(stack, 1, 2, 3);
		float s_x = stack.popFloat();
		float s_y = stack.popFloat();
		float s_z = stack.popFloat();

		assertTrue(Vector3_UW._equals_default(stack, r_x, r_y, r_z, s_x, s_y,
				s_z));
	}

	@Test
	public void equalsMethodTest() {
		ValueTypeStack stack = ValueTypeStack.current();
		// Vector3 r = new Vector3(1, 2, 3);
		Vector3_UW._constructor(stack, 1, 2, 3);
		float r_x = stack.popFloat();
		float r_y = stack.popFloat();
		float r_z = stack.popFloat();

		// Vector3 s = new Vector3(1, 2, 3);
		Vector3_UW._constructor(stack, 1, 2, 3);
		float s_x = stack.popFloat();
		float s_y = stack.popFloat();
		float s_z = stack.popFloat();

		assertTrue(Vector3_UW._equals(stack, r_x, r_y, r_z, s_x, s_y, s_z));
	}
}
